package com.qire.manhua.outer;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.qire.antsbinder.dal.Observer;
import com.qire.antscore.annotation.DeepLink;
import com.qire.antsdeeplink.DeepLinkUri;
import com.qire.antsrouter.AntsRouter;
import com.qire.antsrouter.card.FloorCard;
import com.qire.common.basic.ObjectUtil;
import com.qire.common.basic.StringUtil;
import com.qire.common.constant.CustomEvent;
import com.qire.common.constant.Navigation;
import com.qire.common.function.Consumer;
import com.qire.common.utils.NoticeEventBus;
import com.qire.manhua.dal.service.UploadFileService;
import com.qire.manhua.model.entity.ComicBookEntity;
import com.qire.manhua.model.enumeration.PageTabIndex;
import com.qire.manhua.model.vo.FileResponseVO;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@DeepLink(path = "qrbridge://")
public class QrBridgeDeepLinkHandler {

    private Map<String, String> parseJsonParams(String json) {
        return new Gson().fromJson(json, new TypeToken<Map<String, String>>(){}.getType());
    }

    public boolean app_util_openNormalWindow(DeepLinkUri deepLinkUri) {
//        param -> {"title":"奇热漫画怎么收费？","url":"https://m.qrcomic.com/help/detail/id/6"}
//        version -> 1.0.2
        Map<String, String> queryParams = deepLinkUri.encodedQueryParams();
        Map<String, String> dataParams = parseJsonParams(queryParams.get("param"));
        AntsRouter.ROUTER.<FloorCard>buildCard(Navigation.Page.WebPage)
                .withData("title", dataParams.get("title"))
                .withData("url", dataParams.get("url"))
                .navigation();

        // true 则不会继续投递，否则会继续投递
        return true;
    }

    public boolean app_util_openMangaWindow(DeepLinkUri deepLinkUri) {
        //qrbridge://app_util_openMangaWindow?param={"id":10956}&version=1.0.1
        Map<String, String> queryParams = deepLinkUri.encodedQueryParams();
        Map<String, String> dataParams = parseJsonParams(queryParams.get("param"));

        System.out.println("app_util_openMangaWindow =======" + dataParams.get("id"));
        int comicBookId = StringUtil.valueToInt(dataParams.get("id"), -1);
        if(comicBookId == -1) {
            return true;
        }

        AntsRouter.ROUTER.<FloorCard>buildCard(Navigation.Page.ComicDetailPage)
                .withData("comicBookId", comicBookId)
                .navigation();

        // true 则不会继续投递，否则会继续投递
        return true;
    }

    public boolean app_util_closeWindow(DeepLinkUri deepLinkUri) {
        NoticeEventBus.NOTICE.sendEvent(CustomEvent.WEB_JAVASCRIPT_CALLBACK, "finish@WebActivity");
        return true;
    }

    public boolean app_util_uploadPics(DeepLinkUri deepLinkUri) {
        /**
         * "uploadCgi" -> "https://res.qiremanhua.com/app/uploadPics/i.php?uploadName=bugfiles"
         * "callbackWeb" -> "appUploadsCallback"
         * "callbackTag" -> "bugfiles"
         * "uploadMax" -> 9.0
         * "uploadWidth" -> 0.0
         * "uploadHeight" -> 0.0
         */
        Map<String, String> queryParams = deepLinkUri.encodedQueryParams();
        Map<String, String> dataParams = parseJsonParams(queryParams.get("param"));

        String uploadApiUrl = dataParams.get("uploadCgi");  // 上传文件API接口Url
        String jsFunctionName = dataParams.get("callbackWeb");  // 通知web页回调用的JS方法名
        String jsFunctionParam = dataParams.get("callbackTag");  // JS方法的tag参数的值。tag参数是web端JS定义的，固定值

        // 构建一个上传文件api接口回调
        UploadApiCallback uploadApiCallback = new UploadApiCallback(jsFunctionName).setTagParam(jsFunctionParam);
        // 构建一个上传服务指定上传api接口URL和接口执行成功后的回调。
        UploadFileService uploadFileService = new UploadFileService(uploadApiUrl, uploadApiCallback);
        // 打开图片选择器页，并将最大可选择图片数 与 图片选择完毕后的回调接口传递过去。
        AntsRouter.ROUTER.<FloorCard>buildCard(Navigation.Page.ImagePickerPage)
                .withData("maxCount", queryParams.get("uploadMax"))
                .withData("pickerImageListener", (Consumer<ArrayList<String>>) uploadFileService::uploadImage)
                .navigation();

        return true;
    }

    public boolean book_reader(DeepLinkUri deepLinkUri) {
        //qrbridge://book_reader?b_id=10956&b_name=pushb&c_id=75120&c_name=pushc
        Map<String, String> queryParams = deepLinkUri.encodedQueryParams();

        String comicName = queryParams.get("b_name");
        int comicId = StringUtil.valueToInt(queryParams.get("b_id"), -1);
        int chapterID = StringUtil.valueToInt(queryParams.get("c_id"), -1);

        if(comicId == -1) {
            return true;
        }

        final ComicBookEntity comicBookEntity = chapterID == -1 ? new ComicBookEntity(comicId, comicName) : new ComicBookEntity(comicId, comicName, chapterID);
        AntsRouter.ROUTER.<FloorCard>buildCard(Navigation.Page.ComicReaderPage)
                .withData("comicBookEntity", comicBookEntity)
                .navigation();

        // true 则不会继续投递，否则会继续投递
        return true;
    }

    public boolean book_shelf(DeepLinkUri deepLinkUri) {
        //qrbridge://book_shelf
        AntsRouter.ROUTER.<FloorCard>buildCard(Navigation.Page.HomePage)
                .withData("tabIndex", PageTabIndex.TAB_INDEX_HOME_BOOKSHELF)
                .withData("subTabIndex", PageTabIndex.TAB_INDEX_BOOKSHELF_FAVORITES)
                .go();
        return true;
    }

    public boolean app_index(DeepLinkUri deepLinkUri) {
        //qrbridge://app_index
        AntsRouter.ROUTER.<FloorCard>buildCard(Navigation.Page.HomePage)
                .withData("tabIndex", PageTabIndex.TAB_INDEX_HOME_RECOMMEND)
                .withData("subTabIndex", PageTabIndex.TAB_INDEX_RECOMMEND_HOT)
                .go();
        return true;
    }


    /**
     * 专门接受上传文件后处理API回调的观察者
     */
    private class UploadApiCallback implements Observer {

        private final JavascriptWrapper javascriptWrapper = new JavascriptWrapper();

        private UploadApiCallback(String functionName) {
            javascriptWrapper.functionName = functionName;
        }

        public UploadApiCallback setTagParam(String value) {
            javascriptWrapper.addParam("tag", value);
            return this;
        }

        @Override
        public <T> void update(String tag, T data, boolean isCache) {
            FileResponseVO dataVO = ObjectUtil.as(data, FileResponseVO.class);
            if(ObjectUtil.nonNull(dataVO)) {
                javascriptWrapper.addParam("successImg", dataVO.successImg);
                javascriptWrapper.sendJavaScriptCallBack();
            }
        }
    }

    /**
     * Javascript包装器，用于封装一个JS回调需要的所有信息。
     */
    private class JavascriptWrapper {
        public String functionName;
        public HashMap<String, Object> functionParam = new HashMap<>();

        public JavascriptWrapper addParam(String name, Object value) {
            functionParam.put(name, value);
            return this;
        }

        public String buildJs() {
            return String.format("%s(%s)", functionName, new Gson().toJson(functionParam));
        }

        public void sendJavaScriptCallBack() {
            NoticeEventBus.NOTICE.sendEvent(CustomEvent.WEB_JAVASCRIPT_CALLBACK, buildJs());
        }
    }

}
